﻿using CNative.Cloud.CPlatform;
using CNative.Cloud.CPlatform.Transport.Implementation;
using CNative.Cloud.ProxyClientPRC;
using CNative.IModuleServices.Common;
using CNative.IModuleServices.Common.Models;
using CNative.IModuleServices.Common.Models.Events;
using CNative.IModuleServices.User;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;

namespace CNative.Services.ClientRPC
{
    class Program
    {
        static  async Task Main(string[] args)
        {
            //Test.DisplayUnicastAddresses();

           await RPCClientFactory.MainRun(() =>
            {
                Test.ForRoutePath();
                //Test.TestRabbitMq();
                //Test.TestALL();
                //Test.StartRequest(100000);
            });
        }
    }

    class Test
    {
        public static void ForRoutePath()
        {
            var userProxy = RPCClientFactory.CreateProxy<IUserService>();
            var managerProxy = RPCClientFactory.CreateProxy<IManagerService>();

            var a = userProxy.GetDictionary().Result;
            ConsoleC.WriteLine($"GetDictionary：{a}", ConsoleColor.DarkCyan);

            var user3 = userProxy.GetUser().GetAwaiter().GetResult();
            ConsoleC.WriteLine($"GetUser3：{user3}", ConsoleColor.DarkCyan);

            var user4 = userProxy.GetUserName(123456).GetAwaiter().GetResult();
            ConsoleC.WriteLine($"GetUserName：{user4}", ConsoleColor.DarkCyan);
            //return;
            var user5 = userProxy.Create(new UserModel
            {
                Name = "stone",
                Age = 12,
                UserId = 2,
                Sex = Sex.Woman
            }).GetAwaiter().GetResult();
            ConsoleC.WriteLine($"Create User：{user5}", ConsoleColor.DarkCyan);


            var a2 = userProxy.GetDictionary2(new UserModel
            {
                Name = "stone",
                Age = 12,
                UserId = 2,
                Sex = Sex.Woman
            }, 32).Result;
            ConsoleC.WriteLine($"GetDictionary2：{a2.UserId},{a2.Name}", ConsoleColor.DarkCyan);

            var a3 = userProxy.GetDictionary3(new UserModel
            {
                Name = "stone",
                Age = 12,
                UserId = 2,
                Sex = Sex.Woman
            }, 33);
            ConsoleC.WriteLine($"GetDictionary3：{a3.UserId},{a3.Name}", ConsoleColor.DarkCyan);

            var a4 = userProxy.GetDictionary3(new UserModel
            {
                Name = "stone",
                Age = 12,
                UserId = 2,
                Sex = Sex.Woman
            }, 37);
            ConsoleC.WriteLine($"GetDictionary3：{a4.UserId},{a4.Name}", ConsoleColor.DarkCyan);

            //var a3 = userProxy.GetApiResult().Result;
            //ConsoleC.WriteLine($"GetDictionary2：{a3.Value.UserId},{a3.Value.Name}", ConsoleColor.DarkCyan);

            var bb = managerProxy.SayHello("XJH").Result;
            ConsoleC.WriteLine($"SayHello：{bb}", ConsoleColor.DarkCyan);

            bb = managerProxy.SayHello2("XJH");
            ConsoleC.WriteLine($"SayHello2：{bb}", ConsoleColor.DarkCyan);

            var user = userProxy.GetUser(new UserModel
            {
                UserId = 1,
                Name = "stone",
                Age = 120,
                Sex = 0
            }).GetAwaiter().GetResult();
            ConsoleC.WriteLine($"GetUser：{user.UserId},{user.Name}", ConsoleColor.DarkCyan);

            var user2 = userProxy.GetUser(new List<int> { 1,23,4}).GetAwaiter().GetResult();
            ConsoleC.WriteLine($"GetUser2：{user2}", ConsoleColor.DarkCyan);
           

            var a5 = userProxy.GetDictionary3(new UserModel
            {
                UserId = 1,
                Name = "stone",
                Age = 120,
                Sex = 0
            }, 38);
            ConsoleC.WriteLine($"GetDictionary3：{a5.UserId},{a5.Name}", ConsoleColor.DarkCyan);

#if NET461
            var wcfTestProxy = RPCClientFactory.CreateProxy<CNative.Modules.WCFTestContract.IServiceTest>();
            var getDate = wcfTestProxy.GetDate();
            ConsoleC.WriteLine($"GetDate：{getDate}", ConsoleColor.DarkCyan);

            var getBySummarie = wcfTestProxy.getBySummarie("xjh");
            ConsoleC.WriteLine($"getBySummarie：{getBySummarie}", ConsoleColor.DarkCyan);

            var addCar = wcfTestProxy.AddCar(new Modules.WCFTestContract.MyCar()
            {
                id = "1",
                name = "ff",
                msg1 = "测试",
                wf = new Modules.WCFTestContract.WeatherForecast() { code = 22, Date = DateTime.Now, myCar = new Modules.WCFTestContract.MyCar2() { name = "adb" } },
                wfList = new List<Modules.WCFTestContract.WeatherForecast>() {
                new Modules.WCFTestContract.WeatherForecast() { code = 22, Date = DateTime.Now, myCar = new Modules.WCFTestContract.MyCar2() { name = "adb3" } }
                }
            });
            ConsoleC.WriteLine($"addCar：{addCar}", ConsoleColor.DarkCyan);

            var addCar2 = wcfTestProxy.AddCar2(null,new Modules.WCFTestContract.MyCar()
            {
                id = "1",
                name = "ff",
                msg1 = "测试",
                wf = new Modules.WCFTestContract.WeatherForecast() { code = 22, Date = DateTime.Now, myCar = new Modules.WCFTestContract.MyCar2() { name = "adb" } },
                wfList = new List<Modules.WCFTestContract.WeatherForecast>() {
                new Modules.WCFTestContract.WeatherForecast() { code = 22, Date = DateTime.Now, myCar = new Modules.WCFTestContract.MyCar2() { name = "adb3" } }
                }
            },"12");
            ConsoleC.WriteLine($"addCar2：{addCar2}", ConsoleColor.DarkCyan);
#endif
            //var userProxyi = RPCClientFactory.CreateProxy<IUserService>();
            //Task.Run(async () =>
            //{
            //    var res = await userProxyi.GetDictionary2(new UserModel
            //    {
            //        UserId = 1,
            //        Name = "stone",
            //        Age = 120,
            //        Sex = 0
            //    }, 35);
            //});

            //var s = userProxy.Result;
            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }

        public static void TestRabbitMq()
        {
            var proxy = RPCClientFactory.CreateProxy<IUserService>();
            proxy.PublishThroughEventBusAsync(new UserEvent()
            {
                Age = 18,
                Name = "stone",
                UserId = 31
            });
            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }

        public static void TestALL()
        {
            Task.Run(async () =>
            {
                RpcContext.GetContext().SetAttachment("xid", 124);

                var userProxy = RPCClientFactory.CreateProxy<IUserService>();
                var managerProxy = RPCClientFactory.CreateProxy<IManagerService>();
                var testProxy = RPCClientFactory.CreateProxy<IModuleServices.Test.ITestService>();

                //var asyncProxy = RPCClientFactory.CreateProxy<IAsyncService>();
                //var result= await  asyncProxy.AddAsync(1, 2);
                var user = userProxy.GetUser(new UserModel
                {
                    UserId = 1,
                    Name = "stone",
                    Age = 120,
                    Sex = 0
                }).GetAwaiter().GetResult();
                var e = userProxy.SetSex(Sex.Woman).GetAwaiter().GetResult();
                var v = userProxy.GetUserId("stone").GetAwaiter().GetResult();
                var fa = userProxy.GetUserName(1).GetAwaiter().GetResult();
                //userProxy.Try().GetAwaiter().GetResult();
                var v1 = userProxy.GetUserLastSignInTime(1).Result;
                var things = userProxy.GetAllThings().Result;
                var apiResult = userProxy.GetApiResult().GetAwaiter().GetResult();
                try
                {
                    userProxy.PublishThroughEventBusAsync(new UserEvent
                    {
                        UserId = 12,
                        Name = "xjh"
                    }).Wait();

                    userProxy.PublishThroughEventBusAsync(new UserEvent
                    {
                        UserId = 11,
                        Name = "xjh3"
                    }).Wait();
                }
                catch (Exception ex) { ConsoleC.WriteLine(ex); }

                var r = await userProxy.GetDictionary();

                var bb = await managerProxy.SayHello("XJH_");
                Console.WriteLine($"SayHello：{bb}");

                var btb = await testProxy.SayHello("TEST");
                Console.WriteLine($"TEST SayHello：{btb}");

                const int noOfClients = 10000;
                var tasks = new Task[noOfClients];

                Console.WriteLine($"Press any key to continue,将循环调用{noOfClients}次...");
                Console.ReadLine();
#if NET461
                var wcfTestProxy = RPCClientFactory.CreateProxy<CNative.Modules.WCFTestContract.IServiceTest>();
                var getDate = wcfTestProxy.GetDate();
                ConsoleC.WriteLine($"GetDate：{getDate}", ConsoleColor.DarkCyan);

                var getBySummarie = wcfTestProxy.getBySummarie("xjh");
                ConsoleC.WriteLine($"getBySummarie：{getBySummarie}", ConsoleColor.DarkCyan);

                var addCar = wcfTestProxy.AddCar(new Modules.WCFTestContract.MyCar()
                {
                    id = "1",
                    name = "ff",
                    msg1 = "测试",
                    wf = new Modules.WCFTestContract.WeatherForecast() { code = 22, Date = DateTime.Now, myCar = new Modules.WCFTestContract.MyCar2() { name = "adb" } },
                    wfList = new List<Modules.WCFTestContract.WeatherForecast>() {
                new Modules.WCFTestContract.WeatherForecast() { code = 22, Date = DateTime.Now, myCar = new Modules.WCFTestContract.MyCar2() { name = "adb3" } }
                }
                });
                ConsoleC.WriteLine($"addCar：{addCar}", ConsoleColor.DarkCyan);
#endif
                do
                {
                    Console.WriteLine($"正在循环 {noOfClients}次调用 GetUser.....");
                    //1w次调用
                    var watch = Stopwatch.StartNew();
                    for (var i = 0; i < noOfClients; i++)
                    {
                        tasks[i] = Task.Factory.StartNew((object clientNo) =>
                        {
                            try
                            {
                                //System.Threading.Thread.Sleep(100);
                                //var a = userProxy.GetDictionary().Result;

                                var a = userProxy.GetDictionary2(new UserModel
                                {
                                    Name = "stone",
                                    Age = 12,
                                    UserId = 2,
                                    Sex = Sex.Woman
                                }, i).Result;
                                Console.WriteLine($"GetDictionary2：{a.UserId},{a.Name}");

                                //var b = managerProxy.SayHello("XJH_" + clientNo).Result;
                                //Console.WriteLine($"SayHello：{b}");

#if NET461
                                var addCar2 = wcfTestProxy.AddCar(new Modules.WCFTestContract.MyCar()
                                {
                                    id = "1",
                                    name = "ff",
                                    msg1 = "测试",
                                    wf = new Modules.WCFTestContract.WeatherForecast() { code = 22, Date = DateTime.Now, myCar = new Modules.WCFTestContract.MyCar2() { name = "adb" } },
                                    wfList = new List<Modules.WCFTestContract.WeatherForecast>() {
                                        new Modules.WCFTestContract.WeatherForecast() { code = 22, Date = DateTime.Now, myCar = new Modules.WCFTestContract.MyCar2() { name = "adb3" } }
                                    }
                                });
                                ConsoleC.WriteLine($"addCar：{addCar2}", ConsoleColor.DarkCyan);
#endif
                                //var result = serviceProxyProvider.Invoke<object>(new Dictionary<string, object>(), "api/user/GetDictionary", "User").Result;
                            }
                            catch { System.Threading.Thread.Sleep(100); }
                        }, i + 1);
                    }
                    Task.WaitAll(tasks);

                    watch.Stop();
                    Console.WriteLine($"{noOfClients}次调用结束，执行时间：{watch.ElapsedMilliseconds}ms");
                    Console.WriteLine("Press any key to continue, q to exit the loop...");
                    var key = Console.ReadLine();
                    if (key.ToLower() == "q")
                        break;
                } while (true);
            }).Wait();
        }


        private static int _endedConnenctionCount = 0;
        private static DateTime begintime;
        public static void StartRequest(int connectionCount = 300000)
        {
            var sw = new Stopwatch();
            sw.Start();
            var userProxy = RPCClientFactory.CreateProxy<IUserService>();
            sw.Stop();
            ConsoleC.WriteLine($"代理所花{sw.ElapsedMilliseconds}ms", ConsoleColor.DarkGray);

            ThreadPool.SetMinThreads(100, 100);
            Parallel.For(0, connectionCount / 6000, new ParallelOptions() { MaxDegreeOfParallelism = 50 }, async u =>
            {
                for (var i = 0; i < 6000; i++)
                    await TestRequest(userProxy, i, connectionCount);
            });
        }
        private static async Task TestRequest(IUserService userProxy, int i, int connectionCount)
        {
            var ab = await userProxy.GetDictionary();
            ConsoleC.WriteLine($"GetDictionary：{ab}", ConsoleColor.DarkGray);
            var a = await userProxy.GetDictionary2(new UserModel
            {
                Name = "stone",
                Age = 12,
                UserId = 2,
                Sex = Sex.Woman
            }, i);
            ConsoleC.WriteLine($"GetDictionary2：{a.UserId},{a.Name}", ConsoleColor.DarkCyan);

            IncreaseSuccessConnection(connectionCount);
        }
        private static void IncreaseSuccessConnection(int connectionCount)
        {
            Interlocked.Increment(ref _endedConnenctionCount);
            if (_endedConnenctionCount == 1)
                begintime = DateTime.Now;
            if (_endedConnenctionCount >= connectionCount)
                Console.WriteLine($"结束时间{(DateTime.Now - begintime).TotalMilliseconds}");
        }

        public static void DisplayUnicastAddresses()
        {
            Console.WriteLine("Unicast Addresses");
            NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in adapters)
            {
                IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
                UnicastIPAddressInformationCollection uniCast = adapterProperties.UnicastAddresses;
                if (uniCast.Count > 0)
                {
                    Console.WriteLine(adapter.Description);
                    string lifeTimeFormat = "dddd, MMMM dd, yyyy  hh:mm:ss tt";
                    foreach (UnicastIPAddressInformation uni in uniCast)
                    {
                        DateTime when;

                        Console.WriteLine("  Unicast Address ......................... : {0}", uni.Address);
                        Console.WriteLine("     Prefix Origin ........................ : {0}", uni.PrefixOrigin);
                        Console.WriteLine("     Suffix Origin ........................ : {0}", uni.SuffixOrigin);
                        Console.WriteLine("     Duplicate Address Detection .......... : {0}",
                            uni.DuplicateAddressDetectionState);

                        // Format the lifetimes as Sunday, February 16, 2003 11:33:44 PM
                        // if en-us is the current culture.

                        // Calculate the date and time at the end of the lifetimes.
                        when = DateTime.UtcNow + TimeSpan.FromSeconds(uni.AddressValidLifetime);
                        when = when.ToLocalTime();
                        Console.WriteLine("     Valid Life Time ...................... : {0}",
                            when.ToString(lifeTimeFormat, System.Globalization.CultureInfo.CurrentCulture)
                        );
                        when = DateTime.UtcNow + TimeSpan.FromSeconds(uni.AddressPreferredLifetime);
                        when = when.ToLocalTime();
                        Console.WriteLine("     Preferred life time .................. : {0}",
                            when.ToString(lifeTimeFormat, System.Globalization.CultureInfo.CurrentCulture)
                        );

                        when = DateTime.UtcNow + TimeSpan.FromSeconds(uni.DhcpLeaseLifetime);
                        when = when.ToLocalTime();
                        Console.WriteLine("     DHCP Leased Life Time ................ : {0}",
                            when.ToString(lifeTimeFormat, System.Globalization.CultureInfo.CurrentCulture)
                        );
                    }
                    Console.WriteLine();
                }
            }
        }
    }
}
